const { ipcRenderer } = require('electron'); // 引入 Electron 的 ipcRenderer 模块，用于主进程和渲染进程之间的通信
let randomNumbersArray = Array(6).fill().map(() => Array(50).fill(128)); // 创建一个 6x50 的数组，每个元素初始化为 128
let smoothedNumbersArray = randomNumbersArray.map(arr => arr.slice()); // 复制随机数数组，用于存储平滑处理后的数据
let angleStepArray = []; // 存储每个动效的角度步长
let noiseOffsetArray = Array(6).fill(0); // 用于生成噪声效果的偏移量数组
const smoothingWindow = 5; // 平滑窗口大小

let maxWaveRadiusArray = [300, 300, 300, 300, 300, 300]; // 每个动效的最大波形半径
let ringSizeArray = Array(6).fill(0); // 每个动效的圆环大小
let ringColorArray = [ // 每个动效的圆环颜色
    [255, 0, 0],    // 红色
    [0, 255, 0],    // 绿色
    [0, 0, 255],    // 蓝色
    [255, 255, 0],  // 黄色
    [255, 0, 255],  // 洋红色
    [0, 255, 255]   // 青色
];

let gradientColors = [ // 每个动效的颜色渐变
    [[0, 255, 255], [255, 0, 255]], // 青色到洋红色
    [[255, 0, 0], [255, 165, 0]],   // 红色到橙色
    [[0, 128, 0], [0, 255, 0]],     // 绿色到亮绿色
    [[0, 0, 255], [75, 0, 130]],    // 蓝色到靛蓝色
    [[255, 20, 147], [255, 105, 180]], // 深粉色到粉红色
    [[75, 0, 130], [238, 130, 238]]    // 靛蓝色到紫罗兰色
];

// 用于存储 Web Worker 实例
let workers = [];

function setup() {
    createCanvas(windowWidth, windowHeight); // 创建画布，大小为窗口宽度和高度
    angleMode(DEGREES); // 将角度模式设置为度
    noFill(); // 取消填充颜色
    strokeWeight(2); // 设置描边宽度为 2
    angleStepArray = Array(6).fill(0).map(() => 360 / (width / 12)); // 初始化每个动效的角度步长数组

    for (let i = 0; i < 6; i++) { // 初始化 6 个 Web Worker
        workers[i] = new Worker('worker.js'); // 创建新的 Worker 实例
        workers[i].onmessage = handleWorkerMessage; // 设置 Worker 的消息处理函数
    }
}

function draw() {
    background(0); // 设置背景为黑色

    for (let i = 0; i < 6; i++) { // 循环绘制 6 个动效
        push(); // 保存当前绘制状态
        translate((i % 3 + 1) * width / 4, (Math.floor(i / 3) + 1) * height / 3); // 将原点平移到对应的位置

        // 创建颜色渐变
        let gradient = drawingContext.createLinearGradient(0, -height / 6, 0, height / 6);
        gradient.addColorStop(0, color(...gradientColors[i][0])); // 设置渐变起始颜色
        gradient.addColorStop(1, color(...gradientColors[i][1])); // 设置渐变结束颜色
        drawingContext.strokeStyle = gradient; // 应用渐变颜色

        beginShape(); // 开始绘制形状
        for (let j = 0; j < smoothedNumbersArray[i].length / 3; j++) { // 循环绘制每个点
            let angle = j * angleStepArray[i]; // 计算当前点的角度
            let baseRadius = map(smoothedNumbersArray[i][j], 0, 255, 100, maxWaveRadiusArray[i]); // 映射半径值
            let noiseFactor = map(noise(noiseOffsetArray[i] + j * 0.1), 0, 1, 0.8, 1.2); // 添加噪声因子
            let radius = baseRadius * noiseFactor; // 计算最终半径
            let x = radius * cos(angle); // 计算 x 坐标
            let y = radius * sin(angle); // 计算 y 坐标
            curveVertex(x, y); // 绘制曲线顶点
        }
        endShape(CLOSE); // 结束绘制形状

        noiseOffsetArray[i] += 0.01; // 更新噪声偏移量

        let randomR = Math.random() * 255;
        let randomG = Math.random() * 255;
        let randomB = Math.random() * 255;
        ringColorArray[i][0] = randomR;
        ringColorArray[i][1] = randomG;
        ringColorArray[i][2] = randomB;

        stroke(ringColorArray[i]); // 设置圆环颜色
        ellipse(0, 0, ringSizeArray[i] * 2, ringSizeArray[i] * 2); // 绘制圆环

        pop(); // 恢复之前保存的绘制状态
    }
}

// 监听来自主进程的 'random-number' 事件
ipcRenderer.on('random-number', (event, randomNumber) => {
    for (let i = 0; i < 6; i++) { // 循环处理每个动效
        if (randomNumbersArray[i].length > width / 2) {
            randomNumbersArray[i].splice(0, 1); // 保持数组长度
        }
        let randomFactor = Math.random(); // 生成一个随机数
        let randomFactor1 = Math.random(); // 生成一个随机数
        randomNumbersArray[i].push(randomNumber * randomFactor * randomFactor1); // 将新随机数乘以随机因子后添加到数组中

        workers[i].postMessage({// 向每个 Worker 发送消息
            index: i,
            randomNumber: randomNumber,
            randomNumbers: randomNumbersArray[i], // 发送随机数数组
            smoothedNumbers: smoothedNumbersArray[i], // 发送平滑处理后的数组
            ringSize: ringSizeArray[i], // 发送圆环大小
            maxWaveRadius: maxWaveRadiusArray[i]
        });
    }
});


function handleWorkerMessage(event) {
    let data = event.data; // 获取 Worker 返回的数据
    let i = data.index; // 获取动效索引

    smoothedNumbersArray[i] = data.smoothedNumbers; // 更新平滑处理后的数组
    ringSizeArray[i] = data.ringSize; // 更新圆环大小
}